package org.walkerljl.boss.openservice.support;


import org.walkerljl.boss.support.common.TraceUtils;
import org.walkerljl.boss.support.sdk.BossCode;
import org.walkerljl.boss.support.sdk.Message;
import org.walkerljl.commons.exception.AppException;

import java.util.Collection;

/**
 * 基础SDK业务实现类
 *
 * @author lijunlin
 */
public abstract class BaseSdkServiceImpl {

    /**
     * 异常消息(构建响应消息失败)
     */
    private static final String EXCEPTION_MSG_BUILD_RES_MSG = "构建响应消息失败";
    /**
     * 批量操作数据最大数量
     */
    private static final int BATCH_OPERTAION_AMOUNT_LIMIT = 50;
    /**
     * 批量操作数据最大数量超限提示消息
     */
    private static final String BATCH_OPERTAION_AMOUNT_LIMIT_MSG = String.format("批量操作数据超过%s条", BATCH_OPERTAION_AMOUNT_LIMIT);

    /**
     * 响应成功消息
     *
     * @param messagePrefix 消息前缀
     * @param reponse       响应数据
     * @param requests      请求参数列表
     * @return
     */
    protected <T> Message<T> toSuccessMessage(String messagePrefix, T reponse, Object... requests) {
        Message<T> message = null;
        try {
            // ready
            message = Message.success(reponse);// rpc message
            String requestString = TraceUtils.toString(requests);// 请求String
            String responseString = TraceUtils.toString(message);// 响应String
            // trace
            TraceUtils.info(messagePrefix, requestString, responseString);
        } catch (Throwable e) {
            message = Message.failure(BossCode.FAILURE.getCode(), EXCEPTION_MSG_BUILD_RES_MSG);
            TraceUtils.traceExceptionQuietly(EXCEPTION_MSG_BUILD_RES_MSG, e);
        }
        return message;
    }

    /**
     * 响应失败消息
     *
     * @param messagePrefix 消息前缀 requests 请求参数列表
     * @return
     */
    protected <T> Message<T> toFailureMessage(String messagePrefix, Object... requests) {
        return toFailureMessage(messagePrefix, null, null, requests);
    }

    /**
     * 响应失败消息
     *
     * @param messagePrefix 消息前缀
     * @param e             异常对象
     * @param requests      请求参数列表
     * @return
     */
    protected <T> Message<T> toFailureMessage(String messagePrefix, Throwable e, Object... requests) {
        return toFailureMessage(messagePrefix, e, null, requests);
    }

    /**
     * 响应失败消息
     *
     * @param messagePrefix 消息前缀
     * @param e             异常对象
     * @param alarmKey      UMP自定义监控Key
     * @param requests      请求参数列表
     * @return
     */
    protected <T> Message<T> toFailureMessage(String messagePrefix, Throwable e, String alarmKey, Object... requests) {
        Message<T> message = null;
        try {
            // ready
            if (e != null && e instanceof AppException) {
                int errCode = ((AppException) e).getCode();
                message = Message.failure(errCode, e.getMessage());
            }
            String requestString = TraceUtils.toString(requests);// 请求String
            String responseString = TraceUtils.toString(message);// 响应String
            // trace
            TraceUtils.traceExceptionQuietly(messagePrefix, requestString, e, alarmKey);
        } catch (Throwable ex) {
            message = Message.failure(BossCode.FAILURE.getCode(), EXCEPTION_MSG_BUILD_RES_MSG);
            TraceUtils.traceExceptionQuietly(EXCEPTION_MSG_BUILD_RES_MSG, e);
        }
        return message;
    }

    /**
     * 参数预检查
     *
     * @param params
     * @param <T>
     */
    protected <T> void preCheckParams(Collection<T> params) {
        int paramSize = 0;
        // check 参数是否为空
        if (params == null || (paramSize = params.size()) == 0) {
            throw new RuntimeException("参数列表为空");
        }
        // check 参数列表是否超过限制
        if (paramSize > BATCH_OPERTAION_AMOUNT_LIMIT) {
            throw new RuntimeException(BATCH_OPERTAION_AMOUNT_LIMIT_MSG);
        }
    }
}
